{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 聚类\n",
    "\n",
    "熟悉各中聚类算法的调用\n",
    "并用评价指标选择合适的超参数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "#导入必要的工具包\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "from sklearn.cluster import MiniBatchKMeans\n",
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn import metrics\n",
    "\n",
    "from sklearn.decomposition import PCA\n",
    "import time\n",
    "\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 87,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def time_profile(func):\n",
    "    def warpper(*args,**kwargs):\n",
    "        import time\n",
    "        start=time.time()\n",
    "        result=func(*args,**kwargs)\n",
    "        end=time.time()\n",
    "        print('花费时间为{}'.format(end-start))\n",
    "        return result\n",
    "    return warpper"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "path='../event_recommendation_engine_challenge_data/'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [],
   "source": [
    "#读取训练数据\n",
    "used_Event = pd.read_csv(path+'used_Event.csv')\n",
    "col_name=list('c_'+str(x) for x in range(1,101))\n",
    "col_name.append('c_other')\n",
    "X_train = used_Event[col_name]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 79,
   "metadata": {},
   "outputs": [],
   "source": [
    "#X_train = (X_train - X_train.min()) / (X_train.max() - X_train.min())\n",
    "X_train = (X_train ) / X_train.max()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 80,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "the shape of train_image: (13418, 101)\n"
     ]
    }
   ],
   "source": [
    "# 原始输入的特征维数和样本数目\n",
    "print('the shape of train_image: {}'.format(X_train.shape))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 81,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style>\n",
       "    .dataframe thead tr:only-child th {\n",
       "        text-align: right;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>c_1</th>\n",
       "      <th>c_2</th>\n",
       "      <th>c_3</th>\n",
       "      <th>c_4</th>\n",
       "      <th>c_5</th>\n",
       "      <th>c_6</th>\n",
       "      <th>c_7</th>\n",
       "      <th>c_8</th>\n",
       "      <th>c_9</th>\n",
       "      <th>c_10</th>\n",
       "      <th>...</th>\n",
       "      <th>c_92</th>\n",
       "      <th>c_93</th>\n",
       "      <th>c_94</th>\n",
       "      <th>c_95</th>\n",
       "      <th>c_96</th>\n",
       "      <th>c_97</th>\n",
       "      <th>c_98</th>\n",
       "      <th>c_99</th>\n",
       "      <th>c_100</th>\n",
       "      <th>c_other</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>count</th>\n",
       "      <td>13418.000000</td>\n",
       "      <td>13418.000000</td>\n",
       "      <td>13418.000000</td>\n",
       "      <td>13418.000000</td>\n",
       "      <td>13418.000000</td>\n",
       "      <td>13418.000000</td>\n",
       "      <td>13418.000000</td>\n",
       "      <td>13418.000000</td>\n",
       "      <td>13418.000000</td>\n",
       "      <td>13418.000000</td>\n",
       "      <td>...</td>\n",
       "      <td>13418.000000</td>\n",
       "      <td>13418.000000</td>\n",
       "      <td>13418.000000</td>\n",
       "      <td>13418.000000</td>\n",
       "      <td>13418.000000</td>\n",
       "      <td>13418.000000</td>\n",
       "      <td>13418.000000</td>\n",
       "      <td>13418.000000</td>\n",
       "      <td>13418.000000</td>\n",
       "      <td>13418.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>mean</th>\n",
       "      <td>0.001080</td>\n",
       "      <td>0.017866</td>\n",
       "      <td>0.015569</td>\n",
       "      <td>0.012517</td>\n",
       "      <td>0.000644</td>\n",
       "      <td>0.008103</td>\n",
       "      <td>0.000465</td>\n",
       "      <td>0.025410</td>\n",
       "      <td>0.012956</td>\n",
       "      <td>0.010841</td>\n",
       "      <td>...</td>\n",
       "      <td>0.009273</td>\n",
       "      <td>0.009332</td>\n",
       "      <td>0.009375</td>\n",
       "      <td>0.007834</td>\n",
       "      <td>0.003584</td>\n",
       "      <td>0.000130</td>\n",
       "      <td>0.009208</td>\n",
       "      <td>0.004802</td>\n",
       "      <td>0.010508</td>\n",
       "      <td>0.005956</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>std</th>\n",
       "      <td>0.008843</td>\n",
       "      <td>0.036095</td>\n",
       "      <td>0.032001</td>\n",
       "      <td>0.027778</td>\n",
       "      <td>0.008715</td>\n",
       "      <td>0.024103</td>\n",
       "      <td>0.008666</td>\n",
       "      <td>0.060658</td>\n",
       "      <td>0.031972</td>\n",
       "      <td>0.024383</td>\n",
       "      <td>...</td>\n",
       "      <td>0.044270</td>\n",
       "      <td>0.041970</td>\n",
       "      <td>0.038840</td>\n",
       "      <td>0.034683</td>\n",
       "      <td>0.021877</td>\n",
       "      <td>0.008636</td>\n",
       "      <td>0.039642</td>\n",
       "      <td>0.028459</td>\n",
       "      <td>0.048279</td>\n",
       "      <td>0.011477</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>min</th>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>...</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>25%</th>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>...</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.001449</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>50%</th>\n",
       "      <td>0.000457</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>...</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.003932</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>75%</th>\n",
       "      <td>0.001372</td>\n",
       "      <td>0.024390</td>\n",
       "      <td>0.023529</td>\n",
       "      <td>0.014085</td>\n",
       "      <td>0.000555</td>\n",
       "      <td>0.006536</td>\n",
       "      <td>0.000472</td>\n",
       "      <td>0.043478</td>\n",
       "      <td>0.019608</td>\n",
       "      <td>0.019608</td>\n",
       "      <td>...</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.007761</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>max</th>\n",
       "      <td>1.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>...</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>1.000000</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>8 rows × 101 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "                c_1           c_2           c_3           c_4           c_5  \\\n",
       "count  13418.000000  13418.000000  13418.000000  13418.000000  13418.000000   \n",
       "mean       0.001080      0.017866      0.015569      0.012517      0.000644   \n",
       "std        0.008843      0.036095      0.032001      0.027778      0.008715   \n",
       "min        0.000000      0.000000      0.000000      0.000000      0.000000   \n",
       "25%        0.000000      0.000000      0.000000      0.000000      0.000000   \n",
       "50%        0.000457      0.000000      0.000000      0.000000      0.000000   \n",
       "75%        0.001372      0.024390      0.023529      0.014085      0.000555   \n",
       "max        1.000000      1.000000      1.000000      1.000000      1.000000   \n",
       "\n",
       "                c_6           c_7           c_8           c_9          c_10  \\\n",
       "count  13418.000000  13418.000000  13418.000000  13418.000000  13418.000000   \n",
       "mean       0.008103      0.000465      0.025410      0.012956      0.010841   \n",
       "std        0.024103      0.008666      0.060658      0.031972      0.024383   \n",
       "min        0.000000      0.000000      0.000000      0.000000      0.000000   \n",
       "25%        0.000000      0.000000      0.000000      0.000000      0.000000   \n",
       "50%        0.000000      0.000000      0.000000      0.000000      0.000000   \n",
       "75%        0.006536      0.000472      0.043478      0.019608      0.019608   \n",
       "max        1.000000      1.000000      1.000000      1.000000      1.000000   \n",
       "\n",
       "           ...               c_92          c_93          c_94          c_95  \\\n",
       "count      ...       13418.000000  13418.000000  13418.000000  13418.000000   \n",
       "mean       ...           0.009273      0.009332      0.009375      0.007834   \n",
       "std        ...           0.044270      0.041970      0.038840      0.034683   \n",
       "min        ...           0.000000      0.000000      0.000000      0.000000   \n",
       "25%        ...           0.000000      0.000000      0.000000      0.000000   \n",
       "50%        ...           0.000000      0.000000      0.000000      0.000000   \n",
       "75%        ...           0.000000      0.000000      0.000000      0.000000   \n",
       "max        ...           1.000000      1.000000      1.000000      1.000000   \n",
       "\n",
       "               c_96          c_97          c_98          c_99         c_100  \\\n",
       "count  13418.000000  13418.000000  13418.000000  13418.000000  13418.000000   \n",
       "mean       0.003584      0.000130      0.009208      0.004802      0.010508   \n",
       "std        0.021877      0.008636      0.039642      0.028459      0.048279   \n",
       "min        0.000000      0.000000      0.000000      0.000000      0.000000   \n",
       "25%        0.000000      0.000000      0.000000      0.000000      0.000000   \n",
       "50%        0.000000      0.000000      0.000000      0.000000      0.000000   \n",
       "75%        0.000000      0.000000      0.000000      0.000000      0.000000   \n",
       "max        1.000000      1.000000      1.000000      1.000000      1.000000   \n",
       "\n",
       "            c_other  \n",
       "count  13418.000000  \n",
       "mean       0.005956  \n",
       "std        0.011477  \n",
       "min        0.000000  \n",
       "25%        0.001449  \n",
       "50%        0.003932  \n",
       "75%        0.007761  \n",
       "max        1.000000  \n",
       "\n",
       "[8 rows x 101 columns]"
      ]
     },
     "execution_count": 81,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X_train.describe()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 104,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(13418, 32)\n"
     ]
    }
   ],
   "source": [
    "#对数据进行PCA降维\n",
    "pca = PCA(n_components=0.7)\n",
    "pca.fit(X_train)\n",
    "\n",
    "X_train_pca = pca.transform(X_train)\n",
    "\n",
    "# 降维后的特征维数\n",
    "print(X_train_pca.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 105,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\ProgramData\\Anaconda3\\lib\\site-packages\\sklearn\\model_selection\\_split.py:2026: FutureWarning: From version 0.21, test_size will always complement train_size unless both are specified.\n",
      "  FutureWarning)\n"
     ]
    }
   ],
   "source": [
    "# 将训练集合拆分成训练集和校验集，在校验集上找到最佳的模型超参数（PCA的维数）\n",
    "X_train_part, X_val = train_test_split(X_train_pca,train_size = 0.8,random_state = 0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 106,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(10734, 32)\n",
      "(2684, 32)\n"
     ]
    }
   ],
   "source": [
    "#拆分后的训练集和校验集的样本数目\n",
    "print(X_train_part.shape)\n",
    "print(X_val.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 107,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# 一个参数点（聚类数据为K）的模型，在校验集上评价聚类算法性能\n",
    "@time_profile\n",
    "def K_cluster_analysis(K, X_train, X_val):\n",
    "    start = time.time()\n",
    "    \n",
    "    print(\"K-means begin with clusters: {}\".format(K));\n",
    "    \n",
    "    #K-means,在训练集上训练\n",
    "    mb_kmeans = MiniBatchKMeans(n_clusters = K)\n",
    "    mb_kmeans.fit(X_train)\n",
    "    \n",
    "    # 在训练集和测试集上测试\n",
    "    y_val_pred = mb_kmeans.predict(X_val)\n",
    "    \n",
    "    #以前两维特征打印训练数据的分类结果\n",
    "    # K值的评估标准\n",
    "    #常见的方法有轮廓系数Silhouette Coefficient和Calinski-Harabasz Index\n",
    "    #这两个分数值越大则聚类效果越好\n",
    "    #CH_score = metrics.calinski_harabaz_score(X_train,mb_kmeans.predict(X_train))\n",
    "    CH_score = metrics.silhouette_score(X_train,mb_kmeans.predict(X_train))\n",
    "    \n",
    "    end = time.time()\n",
    "    print(\"CH_score: {}, time elaps:{}\".format(CH_score, int(end-start)))\n",
    "    \n",
    "    return CH_score"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 108,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "K-means begin with clusters: 10\n",
      "CH_score: 0.24973214759217596, time elaps:3\n",
      "花费时间为3.545464038848877\n",
      "K-means begin with clusters: 20\n",
      "CH_score: 0.11134120832256365, time elaps:3\n",
      "花费时间为3.5704972743988037\n",
      "K-means begin with clusters: 30\n",
      "CH_score: 0.033716512658287845, time elaps:3\n",
      "花费时间为3.5734689235687256\n",
      "K-means begin with clusters: 40\n",
      "CH_score: 0.04477352048749629, time elaps:3\n",
      "花费时间为3.5785179138183594\n",
      "K-means begin with clusters: 50\n",
      "CH_score: 0.003574174606425117, time elaps:3\n",
      "花费时间为3.656761884689331\n",
      "K-means begin with clusters: 60\n",
      "CH_score: 0.11025105383185524, time elaps:3\n",
      "花费时间为3.718893051147461\n",
      "K-means begin with clusters: 70\n",
      "CH_score: 0.08090726663665021, time elaps:3\n",
      "花费时间为3.6476686000823975\n",
      "K-means begin with clusters: 80\n",
      "CH_score: 0.003056998582371256, time elaps:3\n",
      "花费时间为3.515383005142212\n",
      "K-means begin with clusters: 90\n",
      "CH_score: 0.0927147821176657, time elaps:3\n",
      "花费时间为3.8883423805236816\n",
      "K-means begin with clusters: 100\n",
      "CH_score: 0.038523527194234075, time elaps:3\n",
      "花费时间为3.6617045402526855\n"
     ]
    }
   ],
   "source": [
    "# 设置超参数（聚类数目K）搜索范围\n",
    "Ks = [10, 20, 30,40,50,60,70,80,90,100]\n",
    "CH_scores = []\n",
    "\n",
    "for K in Ks:\n",
    "    ch = K_cluster_analysis(K, X_train_part, X_val)\n",
    "    CH_scores.append(ch)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 109,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0.24973215, 0.11134121, 0.03371651, 0.04477352, 0.00357417,\n",
       "       0.11025105, 0.08090727, 0.003057  , 0.09271478, 0.03852353])"
      ]
     },
     "execution_count": 109,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.array(CH_scores)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 111,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<matplotlib.lines.Line2D at 0x19615ca6fd0>]"
      ]
     },
     "execution_count": 111,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\nwAHRfz2NWreOb5ezZsFttyUdzefde28MmBs0qHTXAvjVr2Id5V/8Ap59NtlYckn6OwDv1nlcm93W\n4D7uvgpYBHTIPtfFzF40s6fM7BsNncDMzjCzGjOrmVuqIxpKTLl2qSs3zzwD06bFV/M069UrpmgY\nMiQaS0uFe4wg7tYtkmqpWjtwa8cdY2K7OXMSjCWHfRr67KxfM7W+fd4HOrn7PsAvgLvNbPPP7eg+\nwt2r3b26qqoqh5AEYvm3Lbcsnd4KlWjkyFhk5PvfTzqSZK2djG3ePLjuuqSjWefhh2M66HwvklII\nW24ZbUMLFiQ7cCuXt6kW2LHO447A7PXtY2ZtgC2ABe6+3N3nA7j7ZKJtYNeWBi1hbZe68ePhiSeS\njqbyLFwY66uedFJhe12Ui/32g+99D66/Ht5/P+lowrBh0Vjar1/SkeRm772jimziRLjoomRiyCXp\nPw/sYmZdzKwt0VA7pt4+Y4D+2Z+PBya4u5tZlZm1BjCzrsAugGaGz6OzzoqqngsuiMFbpeatt2Jo\nfDn6y1+iK2Ca+uY35oorYMWKmKYhaf/6V+EXSSmEU06JaVWuuQbuvz+BAHJp7QWOBl4nSuoXZbcN\nATLZn9sBfwNmAv8Buma3fxeYSvT4eQHo09i51Hun6f74x+gZcPfdSUfiPmeO+1//6j5woHuXLhHX\nxhu7P/FE0pE1zZo17nvu6b7vvklHUnrOPNO9dWv3//432TiOPtq9qsr900+TjaM5li1z339/9802\ny9/7SI69d3LuSlmsm5J+061e7b7XXpFkly0r7rk//tj9wQfdzz03uvVF05r7Flu49+3rPny4++67\nu7dr5z5+fHFja4lJk+L3uPXWpCMpPXPmuG+6qft3vpNcDC+9FH+fX/86uRha6p133LfeOv4/Fi9u\n+fGU9FNm3Lj4a/7mN4U9z7Jl7hMnuv/v/7ofdFCU+CDGDBxxhPuVV0bCXLly3Ws+/DA+lNq2dX/o\nocLGly8DB8Y3lEWLko6kNF1+efzdn3kmmfOfeGJ88CxYkMz58+Wxx9xbtXLv16/lYwyU9FNmzZpI\nuh06uC9cmL/jrlrlXlPjfvXV7j16uG+0UVw1rVrF19PBg90ff9x9yZIvPs78+e7du7tvsIH7P/6R\nv/gK4eOP3TfZxP2005KOpHQtXuy+zTbuhxxS/AFRM2fG9Xf++cU9b6FceWX8T914Y8uOo6SfQjU1\n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\nAABJRU5ErkJggg==\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x19615bcc4a8>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 绘制不同PCA维数下模型的性能，找到最佳模型／参数（分数最高）\n",
    "plt.plot(Ks, np.array(CH_scores), 'b-')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "两个指标的变化趋势类似"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 117,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "K-means begin with clusters: 2\n",
      "CH_score: 0.5606023914241534, time elaps:3\n",
      "花费时间为3.580554723739624\n",
      "K-means begin with clusters: 3\n",
      "CH_score: 0.18477962216344507, time elaps:3\n",
      "花费时间为3.591552972793579\n",
      "K-means begin with clusters: 4\n",
      "CH_score: 0.43112870482795707, time elaps:3\n",
      "花费时间为3.629652976989746\n",
      "K-means begin with clusters: 5\n",
      "CH_score: 0.20143757704721074, time elaps:3\n",
      "花费时间为3.8422508239746094\n",
      "K-means begin with clusters: 6\n",
      "CH_score: 0.32572069019417704, time elaps:3\n",
      "花费时间为3.773037910461426\n",
      "K-means begin with clusters: 7\n",
      "CH_score: 0.27921952193196387, time elaps:3\n",
      "花费时间为3.7298829555511475\n",
      "K-means begin with clusters: 8\n",
      "CH_score: 0.26819435756023424, time elaps:3\n",
      "花费时间为3.6467010974884033\n",
      "K-means begin with clusters: 9\n",
      "CH_score: 0.2582899131455394, time elaps:3\n",
      "花费时间为3.7630088329315186\n",
      "K-means begin with clusters: 10\n",
      "CH_score: 0.17722786992698494, time elaps:3\n",
      "花费时间为3.814147710800171\n"
     ]
    }
   ],
   "source": [
    "# 设置超参数（聚类数目K）搜索范围\n",
    "Ks = [x for x in range(2,11)]\n",
    "CH_scores2 = []\n",
    "\n",
    "for K in Ks:\n",
    "    ch = K_cluster_analysis(K, X_train_part, X_val)\n",
    "    CH_scores2.append(ch)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 116,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<matplotlib.lines.Line2D at 0x19615cd4d30>]"
      ]
     },
     "execution_count": 116,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXcAAAD8CAYAAACMwORRAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMS4wLCBo\ndHRwOi8vbWF0cGxvdGxpYi5vcmcvpW3flQAAIABJREFUeJzt3Xec1NXVx/HPoQqoUQEL7QEDRoXH\nuiEiii0xlAg4K4ruJHaUoKh57JrYOxZUQBELsQGiCEYesRHUJBawRtGIWMCKWLCAiNznj7M8ruvi\nzu7OzJ35zff9evFadvbH/I7r7pk75957roUQEBGRZGkUOwAREck+JXcRkQRSchcRSSAldxGRBFJy\nFxFJICV3EZEEUnIXEUkgJXcRkQRSchcRSaAmsW7cpk2b0Llz51i3FxEpSvPmzfs4hNC2tuuiJffO\nnTszd+7cWLcXESlKZvZ2JtepLCMikkBK7iIiCaTkLiKSQEruIiIJpOQuIpJASu4iIgmk5C4ikkBF\nl9xfeglOOw10OqCIyNoVXXKfPRsuvhimT48diYhI4Sq65D58OHTvDiecAMuXx45GRKQwFV1yb9oU\nRo+Gt96Cyy+PHY2ISGEquuQOsNdeUF4OF14IixbFjkZEpPBklNzNrK+ZvWZmC8zs1Bq+foiZLTGz\n5yv/HJH9UH9o1CifVD3ppFzfSUSk+NSa3M2sMTAG6AdsDRxoZlvXcOnkEMJ2lX8mZDnOH+ncGU45\nBSZPhjlzcn03EZHiksnIvSewIISwMISwEpgEDMptWJk5+WTo1AlGjoRVq2JHIyJSODJJ7u2BqpXt\nxZWPVVduZi+a2VQz61jTE5nZMDOba2ZzlyxZUo9wf6hlS59UffFFGD++wU8nIpIYmSR3q+Gx6luI\n7gM6hxC2AR4GJtb0RCGE8SGEshBCWdu2tR4kkpHycthzTzjzTFi6NCtPKSJS9DJJ7ouBqiPxDsB7\nVS8IISwNIXxT+ekNwI7ZCa92Zr40ctky+POf83VXEZHClklyfwboZmZdzKwZMBSYUfUCM9usyqcD\ngfnZC7F2PXrAiBFw/fXw/PP5vLOISGGqNbmHEFYBxwCz8KQ9JYTwspmda2YDKy8baWYvm9kLwEjg\nkFwFvDZnnw0bbeSTq+o7IyKlzkKkTFhWVhayfUD2DTfAsGFw550wdGhWn1pEpCCY2bwQQllt1xXl\nDtW1Oeww2GEHOPFE+Oqr2NGIiMSTqOTeuDFcfTW8+663JhARKVWJSu4AvXtDOu3tCd54I3Y0IiJx\nJC65A1xyiXeP/NOfYkciIhJHIpN7u3a+5n3GDHjggdjRiIjkXyKTO8Dxx0PXrv5x5crY0YiI5Fdi\nk3vz5nDVVfDaa3DNNbGjERHJr8Qmd4ABA6B/fzjnHPjgg9jRiIjkT6KTO8CVV8KKFXDaabEjERHJ\nn8Qn9y228MO0b7kFnnoqdjQiIvmR+OQO3g54s83g2GNh9erY0YiI5F5JJPf11oNLL4VnnoGJNXaa\nFxFJlpJI7gAVFdCrF5x6Knz+eexoRERyq2SSu5kviVyyBM49N3Y0IiK5VTLJHWDHHeGII7y52Py8\nHiciIpJfJZXcAS64AFq18p2rOtRDRJKq5JJ727ZelnnwQe89IyKSRCWX3AGGD4fu3X39+4oVsaMR\nEcm+kkzuTZvC6NHw5ptw+eWxoxERyb6STO4Ae+0F5eV+YtOiRbGjERHJrpJN7uCnNa1eDSefHDsS\nEZHsKunk3rkznHIKTJoEc+bEjkZEJHtKOrmDj9o7dYKRI2HVqtjRiIhkR8kn95YtfVL1xRdh/PjY\n0YiIZEfJJ3fwidU99vDukUuXxo5GRKThlNzxvjNXXw3LlvnB2iIixU7JvVKPHjBiBFx/PTz/fOxo\nREQaRsm9irPPho028slV9Z0RkWKm5F7Fhhv6pqbHH4fJk2NHIyJSf0ru1Rx2GOywA5x4Inz1Vexo\nRETqR8m9msaNfXL13XfhootiRyMiUj9K7jXo3RvSabjsMnjjjdjRiIjUnZL7WlxyiXeP/J//iR2J\niEjdKbmvRbt2vuZ9+nSYNSt2NCIidaPk/hOOPx66doXjjoOVK2NHIyKSOSX3n9C8OVx1Fbz2Glx7\nbexoREQyp+ReiwEDoH9/3+D0wQexoxERyUxGyd3M+prZa2a2wMxO/Ynr9jOzYGZl2Qsxviuv9LNW\nTz89diQiIpmpNbmbWWNgDNAP2Bo40My2ruG69YCRwFPZDjK2Lbbww7Rvvhmefjp2NCIitctk5N4T\nWBBCWBhCWAlMAgbVcN15wKXAiizGVzDOPBM23RSOPdaP5hMRKWSZJPf2QNUjpBdXPvb/zGx7oGMI\n4W9ZjK2grLceXHqpj9wnTowdjYjIT8skuVsNj/1/z0QzawRcCdS63cfMhpnZXDObu2TJksyjLBAV\nFdCrF5x6Knz+eexoRETWLpPkvhjoWOXzDsB7VT5fD+gB/N3M3gJ2AmbUNKkaQhgfQigLIZS1bdu2\n/lFH0qgRXHMNLFkC554bOxoRkbXLJLk/A3Qzsy5m1gwYCsxY88UQwuchhDYhhM4hhM7Ak8DAEMLc\nnEQc2Y47whFHeHOx+fNjRyMiUrNak3sIYRVwDDALmA9MCSG8bGbnmtnAXAdYiC64AFq18h2sOtRD\nRApRk0wuCiHMBGZWe+wva7l294aHVdjatvWyzHHHwYwZMKimtUMiIhFph2o9DR8O3bv7+vcViVz8\nKSLFTMm9npo2hdGj4c034fLLY0cjIvJDSu4NsNdeUF7u564uWlT79SIi+aLk3kCjRvmO1ZNPjh2J\niMj3lNwbqHNnOOUUmDQJHnssdjQiIk7JPQtOPhk6dfK+M999FzsaEREl96xo2dLXvr/4IsyZEzsa\nEREl96wpL/fmYrfdFjsSEREl96xp0QL22w+mToXly2NHIyKlTsk9iyoq4Isv4G+JbXwsIsVCyT2L\ndt8d2rVTaUZE4lNyz6LGjeGgg2DmTFi6NHY0IlLKlNyzrKICVq2Cu+6KHYmIlDIl9yzbdltvKKbS\njIjEpOSeZWaQTsM//gELF8aORkRKlZJ7Dhx0kH+84464cYhI6VJyz4FOnaBPH7j9dp3UJCJxKLnn\nSDoNr74Kzz4bOxIRKUVK7jmy337QrJkmVkUkDiX3HNlwQxgwwFsBr1oVO5rCpJKVSO4ouedQOg0f\nfACPPho7ksLz8MOw/vrwxhuxIxFJJiX3HOrfHzbYQKWZmowaBV9+CZMnx45EJJmU3HNonXVgyBCY\nNg2++ip2NIVjwQKYNcv/fs89cWMRSSol9xyrqPAR6owZsSMpHNddB02awAknwLx58NZbsSMSSR4l\n9xzbdVfo2FGlmTW+/hpuuglSKfjjH/2xadPixiSSREruOdaokY/eZ82Cjz6KHU18kyfDp596Yu/a\nFbbZBu6+O3ZUIsmj5J4HFRV+cPaUKbEjiW/sWG+s1qePf15eDv/8J7z/fty4RJJGyT0PevTwbpGl\nXpp55hmYO9dH7Wb+WCrl692nT48bm0jSKLnnSToNTz0Fr78eO5J4xoyBddf178Ua3btDt24qzYhk\nm5J7nhx4oI9WS7VT5NKlvlv397/3zUtrmHlpZvZs+OSTePGJJI2Se560bw977OGlmVLcdn/zzfDN\nN9+vkKkqlfI5ifvuy39cIkml5J5H6bRv4Hn66diR5Nfq1TBunE+i9ujx46+XlflyUZVmRLJHyT2P\nUinftXr77bEjya9Zs/xUqppG7eClmVQKHnwQvvgiv7GJJJWSex797Gewzz5ee/7229jR5M/YsbDJ\nJrDvvmu/JpXyss3MmfmLSyTJlNzzLJ2GJUvgoYdiR5Ifb70F998PRx7p/e3Xpndv2Hhj9ZoRyRYl\n9zzr2xc22qh01rxfd53v0j3qqJ++rnFjGDzYXwhWrMhPbCJJpuSeZ82awf77w733Jr++vGIF3Hgj\nDBwIHTrUfn15uXfPfPDB3McmknQZJXcz62tmr5nZAjM7tYavH21mL5nZ82b2hJltnf1QkyOdhuXL\nPcEn2dSp8PHHa59IrW733b3/vUozIg1Xa3I3s8bAGKAfsDVwYA3J+44Qwn+HELYDLgWuyHqkCbLz\nztC5c/JLM2PHwhZbwJ57ZnZ9s2Y+4TxjRmlNOIvkQiYj957AghDCwhDCSmASMKjqBSGEZVU+bQWU\n4DadzJn56P3hh/0YviR67jn417981N6oDsW/8nLvGvn3v+csNJGSkMmvXXtgUZXPF1c+9gNmNsLM\n3sBH7iOzE15yVVT45p5Jk2JHkhtjx0KLFnDwwXX7d3vvDS1bqjQj0lCZJHer4bEfjcxDCGNCCD8H\nTgHOrPGJzIaZ2Vwzm7tkyZK6RZowW24JO+6YzNLMZ5/5Rq2KCq+h10WLFn727LRp3pJACp9WNxWm\nTJL7YqBjlc87AO/9xPWTgME1fSGEMD6EUBZCKGvbtm3mUSZUOu3HzL36auxIsmviRJ8wznQitbry\ncvjwQy/rSOF6+234wx+gVStfFSWFJZPk/gzQzcy6mFkzYCjwgxNBzaxblU8HACXc2DZzQ4d6PTpJ\n7QhWr/aSTK9esP329XuO/v19clWlmcL0ySdw4onwi1/4ATTdusGIEfD887Ejk6pqTe4hhFXAMcAs\nYD4wJYTwspmda2YDKy87xsxeNrPngT8Bday0lqZNN4Vf/zpZnSIffRT+85/6j9rBWwLvvbcn96R8\nX5JgxQq47DL4+c/hiit8cPKf/8Bjj0Hr1jBkCCxbVvvzSJ6EEKL82XHHHYOE8Ne/hgAhPPFE7Eiy\nY999Q2jTJoTlyxv2PDfd5N+XuXOzE5fU36pVIUycGELHjv7/pF+/EF544YfXzJkTQqNGIQwZEsLq\n1XHiLBXA3JBBjtUO1cj23ddXhyShNLNokR+Xd/jh3v2yIQYO9JYEagMcTwjwwAOwww6+6mmTTfyd\n2cyZfrB5VX36wAUXwF13eVlO4lNyj2zddWHQIJg8GVaujB1Nw4wf7wnh6KMb/lytW/uO1bvvVmkm\nhnnzvGTYrx98+aUv2X3qKT9wZm1OPtnnS/70J//3EpeSewFIp32S6oEHYkdSfytXwg03wIABvvs2\nG1Ipr+nOn5+d55PaLVzoR0KWlcGLL8Lo0f79P+CA2jejNWoEf/2rj/CHDPElsRKPknsB+M1voG3b\n4i7NTJvmyxcbMpFa3b77+m5elWZy7+OP4fjjff/F9OlwxhnwxhswcuRPt2qurnVrfxe6aBEcdpje\ndcWk5F4Amjb1kdGMGfD557GjqZ8xY2DzzeG3v83ec262mS+p1JLI3Pn6a7jwQl8Bc801cMghfhTk\n+ef/8CDzuujVCy65xF/wR4/OarhSB0ruBSKd9qVmxZjIXnoJHn8chg+vWx+ZTKRSvn564cLsPm+p\nW7UKJkzwNepnnOHzGy+95PMm7do1/PlPOMHnkk46CZ58suHPJ3Wn5F4gevaErl2Lsx3BuHHQvDkc\nemj2nzuV8o/F+KJXiEKA++6Dbbf107E6dfIX5unTYessNuo2g5tv9j7+BxwAS5dm77klM0ruBWJN\np8jZs+Hdd2NHk7lly+DWW31DS+vW2X/+Ll18p6uSe8M99RTstpsvM121yucy/vlP2GWX3Nxvww19\nB+v77/tSytWrc3MfqZmSewGpqPCR1Z13xo4kc7fe6kvlsjmRWl15ufeZKaYXvULyn//AfvvBTjv5\n38eNg3//298VWU1tAbPol7/03az33w+jRuX2XvJDSu4FpGtX+NWviqc0E4JvWCkr87JSrqwpzST9\n5Kps+/BD7/nSvbsvsz37bJ8sPfpon8TPlxEjfGnk6afDE0/k776lTsm9wKTT8MILPrIqdI89Bq+8\nkttRO8BWW/kSPZVmMvPll3DOOT5YGD8ehg3zZY1nneWb5vLNzPdAdOni9fcS7/adN0ruBWb//X3b\nfTGseR8zxuuqBxyQ+3uVl8OcOb4eW2r27bdecuna1Ufpffv6i++YMb6xKKaf/cxbEyxd6gMY1d9z\nT8m9wGy8sa8Vv/32wv4FeO89X8d86KHeGyfXUik/vGPGjNqvLTUh+LuaHj38XdQWW/gcxV13+VLH\nQrHddnD11fDgg762XnJLyb0ApdO+w+/xx2NHsnYTJviKi+HD83O/7bf3tgbarfpDTzwBvXv7O5sm\nTfzFb84cnzwtREceCQcd5CWi2bNjR5NsSu4FaOBAP92mUEsz334L11/v7zC6ds3PPc189P7ww8W7\nizeb5s+HwYNh1139RKQJE3yuZp99cr8CpiHM/GenWzfvYZPUA+ILgZJ7AWrVyhPZlCmFeT7ljBle\nlsn1RGp1qZQ3KJs5M7/3LSTvvecTpD16+Mj3ggvg9de9zXKTJrGjy8y663rJaNkyH8XrrNzcUHIv\nUOm0j1ALMZGNHes7GwcMyO99e/Xy06tKsTSzahX85S/+TumWW+DYY30FzOmn52fOI9v++799onf2\nbF/ZI9mn5F6g9tzTE1mhlWbmz/cDG44+2lf15FOjRt4p8n//1xtelZIJE+C887xk9+qrcNVV0KZN\n7Kga5tBDvVHZ+ef7JKtkl5J7gWrSxLf0/+1v8OmnsaP53nXX+QaYww+Pc/9UyhN7KSWDb77x8svO\nO/vu5c03jx1R9owZ4z1tKiq0AznblNwLWDrtNeapU2NH4r780ksCQ4b4ks0YdtsNNtqotEozN94I\nixf72vVCniytj5Ytvf6+fLkPZlatih1Rcii5F7AddvCdmYVSmrnjDp8Ey/dEalVNm3pp4r77iv9Y\nwkysWOFrwnv39mPvkmirrXwFzRNPwJlnxo4mOZTcC5iZv12dMwfeeSduLCH4W+htt/XyQEzl5T7Z\n/OijcePIhwkTvFxxzjnJG7VXVVHhq4AuucSbjEnDKbkXuIMO8o933BE3jn/9y8/U/OMf4yeZX//a\nl9MlvdfMihVw0UW+ln3PPWNHk3tXXeWDhz/8If5gJgmU3Avc5pv7W/Lbbot7HuWYMX7s2poXm5jW\nWceXYd57b7LXSN9wg69rT/qofY0WLbz+/u233q+oFMpuuaTkXgTSaXj5ZR85x/DRR/5Ld/DBcboK\n1qS83LsLJrWF7PLlPmrfbTfYY4/Y0eRPt24+gfzkk3DaabGjKW5K7kVgyBBfGhmrz/uNN/poKuZE\nanX9+vkIPqmlmfHj/QSjs8+OHUn+DRkCxxzjh3yoh3/9WYj0Xr+srCzMnTs3yr2L0aBBMHeu1yLz\nuXnou++8NNS1KzzySP7um4nBg2HePP+eJKlssXy5f8+33LJ0m2t9840f//f66/Dss8la299QZjYv\nhFBW23UauReJdNrrr3Pm5Pe+99/vybOQRu1rpFK+/vuZZ2JHkl3XXecNtUp5W37z5t5bCfyMg2++\niRtPMVJyLxK/+x2st17+SzNjx0K7dr62vNDss4+Xq5JUmvn6a18OuOee0KdP7Gji6tLFN83Nmwcn\nnhg7muKj5F4kWrTwQ46nTvW37fmwYAHMmgVHHZXfMzczteGGngTvvjvuSqJsGjfOzz4t5VF7VYMH\nwwknwLXXfj+Sl8wouReRdBq++ML7zeTDuHE+Mj7iiPzcrz5SKX8RKoYzZ2vz1Vdw6aW+jn+XXWJH\nUzguvtgPHzniCK/BS2aU3IvIbrtB+/b5Kc18/TXcfLN3YWzXLvf3q69Bg3wyNQmlmXHjfNmpRu0/\n1KwZTJ7s7x6HDMnfO9dip+ReRBo39tNrZs7M/UHRkyd7N8pCnEitatNNfZRb7I3E1oza9947fnuH\nQtSpE/z1r37a1PHHx46mOCi5F5l02jvn3XVXbu8zdqy3Yt1tt9zeJxtSKXjppeJ+yz5mjG/KKsV1\n7ZkaMABOOcX3ABRKM71CpuReZLbZxo9Yy+UP99NP+5r6Qugjk4lUyj8Wa2nmyy/hssv8TNpevWJH\nU9jOP9977Rx1lB9aImun5F5k1nSK/Mc/YOHC3Nxj7Fg/x/X3v8/N82dbp05QVla8yf3aa73Mplp7\n7Zo08QNLWrb01WOldiJXXSi5F6FcdopcuhQmTfLEvv762X/+XEml/B3HokWxI6mbL77wUXu/fvCr\nX8WOpjisWVTwyiswYkTsaAqXknsR6tTJa+G335799d033+y7AQt9IrW68nL/OG1a3Djq6tpr4ZNP\nVGuvq7339oM9brnFf2blxzJK7mbW18xeM7MFZnZqDV//k5m9YmYvmtkjZvZf2Q9Vqqqo8Jrjs89m\n7zlXr/bleLvu6qfTF5MttoDu3YurNLNsGYwa5ROFPXvGjqb4nHWWd8wcMSIZ+xyyrdbkbmaNgTFA\nP2Br4EAz27raZc8BZSGEbYCpwKXZDlR+aL/9fP1vNte8z5rldfxiG7WvUV4Ojz/ua8WLwTXXaNTe\nEI0be2ly/fX99+HLL2NHVFgyGbn3BBaEEBaGEFYCk4BBVS8IIcwOIayZ2ngS6JDdMKW6DTf0fjN3\n3pm9Q4XHjoVNNvl+9UmxSaX83cf06bEjqd3nn8Pll/v/w7Ja+/vJ2my6qf8OvP66r6BJShuKbMgk\nubcHqk5TLa58bG0OB/63pi+Y2TAzm2tmc5csWZJ5lFKjdNr7kGTjLNE33/QOkEce6e8IitE223hr\n2GIozVx9tW8S06i94fbYw1ca3XGHn14lLpPkXtNK5xpfH80sDZQBl9X09RDC+BBCWQihrG3btplH\nKTXq3x822CA7pZnrr/dllsOGNfy5YjHz0swjj8Bnn8WOZu0++8wPohg4EHbcMXY0yXD66T7JOnIk\nPPdc7GgKQybJfTHQscrnHYD3ql9kZr8GzgAGhhDUfTkPmjf3Xhv33OPb1+trxQo/bWngQOjYsfbr\nC1kq5adG5au5Wn2MHu0JXqP27GnUyAc5bdp4//dly2JHFF8myf0ZoJuZdTGzZsBQYEbVC8xse+B6\nPLEXyXRWMqTTnthnzKj92rWZOtU30RTrRGpVPXv6OuhCLc189hlceaW3st1++9jRJEvbtr5H4803\nvYNkqdffa03uIYRVwDHALGA+MCWE8LKZnWtma45wuAxYF7jLzJ43swakGqmLXXbx0XZDSjNjxvhS\nwr32yl5csTRq5J0sH3igYe9mcuWqq3wyVaP23NhlF7jwQu+9NGZM7Gji0hmqCXDaab7L8b33YOON\n6/Zvn33W675XXpmcbnuzZ/shHlOnfr+5qRB8+il07uz92ou9i2UhW73aS4wPPuib/dZZp35/WrT4\n6a83b57f84zXyPQM1Sb5CEZyK532Aw2mTPFT4+ti3Dj/IT744NzEFsOuu3rt9e67Cyu5X3ml14LP\nOit2JMnWqBFMnOibmxYt8r0EK1b8+M/y5Q0v3TRtWr8Xhv33h969s/PfuzZK7gnQvTtst52XZuqS\n3D/7zFsYHHSQr5tPiiZN/BCPKVO8lULz5rEj8gRz1VX+YrPNNrGjSb7Wrb3+/lNC8D0iy5fXnPwz\n+VPbv122zDfVVX98222V3CVDFRVw0km+maNbt8z+zS23+A9nEiZSq0ulfAXQI4/4ktHYrrjCm4Rp\n1F44zHzk3bRpcTXJy5QahyXEgQf6D2umfd5Xr/YdqTvtBDvskNvYYthrL/+FLYTa9tKlvmlpyJDi\n69kjxUvJPSHat/dJxEw7RT76qI/ykzhqBy/F/O533oogW+0Z6uuKK7zviUbtkk9K7glSUQELFnhf\n89qMHeuTjkOG5D6uWMrLfdT8+OPxYvj4Yx+177+/z42I5IuSe4KkUj4TX9ua90WLfER7+OF+fVL9\n9re+aiFmaebyy329/V/+Ei8GKU1K7gnys5/5+t7Jk30L/tqMH++lm6OOyl9sMbRqBX37+gEeq1fn\n//5Llnhb3wMO8MPGRfJJyT1h0mlPKg89VPPXV670znn9+0OXLvmNLYbyct/c9dRT+b/3qFF+xqdG\n7RKDknvC/Pa3sNFGay/N3HOPtwlO6kRqdQMG+FK3fPea+egjP0LvwANhq63ye28RUHJPnGbNvAxw\n772+rrq6sWN9xN63b/5ji2GDDXy7/z335LeR1KhRvllFo3aJRck9gdJp35x0770/fPyll3zlyPDh\nvkW7VKRSfnzgCy/k534ffeRNqw46CH7xi/zcU6S6EvoVLx29evnovHppZtw4X/996KFx4opl0CB/\nMctXaebSS33U/uc/5+d+IjVRck8gM1/z/vDD8MEH/tiyZXDrrTB0qK9vLyVt20KfPvlZEvnBB176\nSqe9jbJILEruCVVR4cv/1jRPuvVW3yVZKhOp1aVS8Mor8Oqrub3PpZf6iqQzz8ztfURqo+SeUFtu\n6X3ab7vNJxLHjvXPf/nL2JHFse++/nHatNzd4/33vfSVTmfevE0kV5TcEyydhnnzfNPSK6/4qN1q\nOu68BHToAL/6VW5LM5dc4pvHVGuXQqDknmBDh/pE4siR3q996NDYEcWVSvmL3dtvZ/+5338frr8e\n/vAH+PnPs//8InWl5J5gm24Kv/mN14APPRRatowdUVyplH/MRWnm4ou9+6Rq7VIolNwTbtgwb541\nfHjsSOLr2tVPQcp2aebdd33UfvDBsPnm2X1ukfpSck+4VMqPeOvaNXYkhSGVgn/84/slotlw8cXw\n3XdwxhnZe06RhlJyLwFJbutbV+Xlvnqo+u7d+lq82CesDzmkNBqxSfFQcpeS0r27L1PM1m7Viy7y\n/QQatUuhUXKXkmLmo/fZs71c1RCLFsGECXDYYdC5c1bCE8kaJXcpOamUr2y5776GPc9FF3mJR6N2\nKURK7lJyysqgY8eGlWbeecdH7YcfDp06ZS82kWxRcpeSY+aj91mzvN9OfVx4oT/P6adnNzaRbFFy\nl5KUSsE338DMmXX/t2+/DTfdBEcc4e8ARAqRkruUpN69YeON61eaueACH7Wfdlr24xLJFiV3KUmN\nG8PgwXD//X6wRqbefBNuvhmOPNKbkYkUKiV3KVmplNfcH3oo839z4YX+wqBRuxQ6JXcpWXvs4Qdo\n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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x19614d71a20>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 绘制不同PCA维数下模型的性能，找到最佳模型／参数（分数最高）\n",
    "plt.plot(Ks, np.array(CH_scores2), 'b-')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
